iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0

Project-level namespaces
使用第三方庫時,與程式鍊結的庫目標名稱必須是唯一的,但不同的第三方庫可能會使用相同的庫目標名稱,這有可能會導致衝突,因此引入命名空間可以解決這個目標名稱唯一性問題。
所以今天會用一個常見的日誌庫 Google Logging Library 為範例。

語法

有些專案會要求使用者在鍊結他們提供的庫時,要加上命名空間,防止鍊結到錯誤的庫。

target_link_libraries(target_name PUBLIC project_name::library_name)

範例

  1. 下載並編譯 glog

$ git clone https://github.com/google/glog.git
$ cd glog
$ mkdir build
$ cd build
$ cmake -S .. -B build -G "Unix Makefiles"
$ make
$ sudo make install

Install the project...
-- Install configuration: ""
-- Installing: /usr/local/lib/libglog.so.0.7.0
-- Installing: /usr/local/lib/libglog.so.1
-- Installing: /usr/local/lib/libglog.so
-- Installing: /usr/local/include/glog/export.h
-- Installing: /usr/local/include/glog/logging.h
-- Installing: /usr/local/include/glog/raw_logging.h
-- Installing: /usr/local/include/glog/stl_logging.h
-- Installing: /usr/local/include/glog/vlog_is_on.h
-- Installing: /usr/local/include/glog/log_severity.h
-- Installing: /usr/local/include/glog/platform.h
-- Installing: /usr/local/lib/pkgconfig/libglog.pc
-- Installing: /usr/local/lib/cmake/glog/glog-modules.cmake <----⭐ 第一個
-- Installing: /usr/local/lib/cmake/glog/glog-config.cmake<----⭐ 第二個
-- Installing: /usr/local/lib/cmake/glog/glog-config-version.cmake<----⭐ 第三個
-- Installing: /usr/local/lib/cmake/glog/glog-targets.cmake<----⭐ 第四個
-- Installing: /usr/local/lib/cmake/glog/glog-targets-noconfig.cmake<----⭐ 第五個

安裝完後,會發現在 glog 安裝了五個 .cmake 檔案。
其中有兩個是我們之前使用過的

  • config.cmake 讓 find_package 找到
  • version.cmake 讓 find_package 知道此專案的相容性版本

通常,讓專案的函式庫擁有命名空間的通常就是以下這兩個.cmake檔了,內容是設定目標的屬性。

  • targets.cmake
  • targets-xxx.cmake

P.S. 如果使用以下的命令讓此專案用Debug模式編譯,targets-xxx.cmake 會變成 targets-release.cmake,因為今天沒有指定編譯模式,因此產生的檔案會是 targets-noconfig.cmake

$ cmake -DCMAKE_BUILD_TYPE=Release ..

  1. 編輯 Main / CMakeLists.txt

在使用 target_link_libraries 鍊結 glog 的時候,會發現使用到了命名空間

cmake_minimum_required(VERSION 3.22)
# 根據自己的cmake版本來設定最小版本,要小於當前版本
project(cmake_totorial VERSION 1.0.0 LANGUAGES CXX)
# 設定專案名稱為cmake_totorial,版本為1.0.0,且此項目使用C++

find_package(glog REQUIRED)
# 尋找 glogConfig.cmake,REQUIRED 將其設定為必要項目,若找不到則會報錯

message(STATUS "glog_FOUND: ${glog_FOUND}")
message(STATUS "glog_INCLUDE_DIRS: ${glog_INCLUDE_DIRS}")
message(STATUS "glog_LIBRARY_DIRS: ${glog_LIBRARY_DIRS}")
message(STATUS "glog_LIBRARIES: ${glog_LIBRARIES}")
message(STATUS "glog_VERSION: ${glog_VERSION}")
# 顯示glog提供的資訊

add_executable(main src/main.cpp)
# 將main.cpp編譯成可執行文件main
target_link_libraries(main PUBLIC glog::glog)
# 將在glog這個命名空間中的庫鍊結到執行檔main                                                          
  1. 編輯 Main / src / main.cpp
#include <iostream>
#include <glog/logging.h>

int main(int argc, char* argv[])
{
  google::InitGoogleLogging(argv[0]);
  // 初始化glog库
  FLAGS_logtostderr = 1;
  // 設定日誌輸出到終端上
  LOG(INFO) << "Hello, World!";
  // 輸出日誌
  return 0;
} 
  1. 編譯與執行

$ cd Main/build
$ cmake ..

查看輸出訊息可以發現,glog只有提供版本資訊,鍊結方式也不是像OpenCV那樣讓使用者將${OpenCV_LIBS}變數拿去鍊結可執行檔,而是使用命名空間內的glog::glog庫,所以每一個專案的使用方式都不盡相同,在使用第三方庫前都要小心地閱讀手冊。

kai@esoc:~/2023_iT_CMake/Day25/Main/build$ cmake ..
-- The CXX compiler identification is GNU 11.4.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- glog_FOUND: 1
-- glog_INCLUDE_DIRS: 
-- glog_LIBRARY_DIRS: 
-- glog_LIBRARIES: 
-- glog_VERSION: 0.7.0
-- Configuring done
-- Generating done
-- Build files have been written to: /home/kai/2023_iT_CMake/Day25/Main/build

$ make
$ ./main

在終端上會輸出執行時間與所在行數,是一個方便 Debug 專案的日誌庫。

kai@esoc:~/2023_iT_CMake/Day25/Main/build$ ./main 
I20231015 18:02:44.320850 92741 main.cpp:8] Hello, World!

Reference

Project-level namespaces


上一篇
[Day 24] 製作第三方庫( 三)
下一篇
[Day 26] 製作第三方函式庫(四)
系列文
建構屬於自己的C/C++專案 : 我的30天CMake學習之旅29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言